<?php
/**
 * Wrapper Class for Zend_Config_Ini with using Memcached
 *
 * Change log
 *
 * @category   Itc
 * @package    Itc_Config
 * @author     Oleg Subbotin <subwrk@techs.com.ua>
 * @version    $Rev:$ $Date: 2011/07/12 16:41:40 $ $Author: alex $
 * @date       15.12.2009
 */

class Itc_Config_Ini
{
    /**
     * Instance of Cache object
     *
     * @var Zend_Cache_Backend_Memcached
     */
    protected static $cache    = null;

    /**
     * Whether use cache (true) or no (false). It might be usable to turn caching off
     * in development environment and turn it on in production
     *
     * @var bool
     */
    protected static $useCache = false;

    /**
     * Private constructor, class not instantiable
     *
     * @return void
     */
    private final function __construct()
    {
    }

    /**
     * Whether or not use cache
     *
     * @param $cache boolean Turn cache on/off
     * @return void
     */
    public static function setCache($cache)
    {
        self::$useCache = (bool) $cache;
    }

    /**
     * Set cache engine (memcache, file, etc)
     *
     * @param $cache object
     * @return void
     */
    public static function setCacheEngine($cache)
    {
        self::$cache = $cache;
    }

    /**
     * Retrieve Config instance
     *
     * @param  string          $filename
     * @param  string|null     $section
     * @param  boolean|array   $options
     * @return Zend_Config_Ini
     */
    public static function get($filename, $section = null, $options = false)
    {
        if (empty($filename)) {
            throw new Exception('Config file ' . $filename . ' not defined.');
        }

        $key     = self::getDataKey($filename, $section);
        $timeKey = self::getTimeKey($filename, $section);

        // do not use cache - return config object from file
        if (false === self::$useCache) {

            $ini = new Zend_Config_Ini($filename, $section, $options);

        // use cache
        } else {
            $newTime  = filemtime($filename);
            $lastTime = (int) self::$cache->load($timeKey);

            // if cache for this file exists & original file has been
            // modified before the cached version - return cached version
            if (self::$cache->test($key) && $lastTime >= $newTime) {
                $ini = unserialize(self::$cache->load($key));
            } else {
                $ini = new Zend_Config_Ini($filename, $section, $options);

                self::$cache->save(serialize($ini), $key);
                self::$cache->save($newTime, $timeKey);
            }
        }

        return $ini;
    }

    /**
     * Gets data-key in cache
     *
     * @param  string        $filename
     * @param  string|null   $section
     * @return string
     */
    protected static function getDataKey($filename, $section)
    {
        return preg_replace('/([^\w])/i', '_', basename($filename)) . '_' . $section;
    }

    /**
     * Gets data-time-key in cache
     *
     * @param  string        $filename
     * @param  string|null   $section
     * @return string
     */
    protected static function getTimeKey($filename, $section)
    {
        return preg_replace('/([^\w])/i', '_', basename($filename)) . '_time';
    }
}
